public class CalendarSeeker {

    final int GREGORIAN_YEAR = 1582;

    private int day, month, year;

    static class WrongDateFormatException extends IllegalArgumentException {
        WrongDateFormatException(String message) {
            super(message);
        }
    }

    enum Month {
        JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER;

        static int getMonthIndex(String s) throws WrongDateFormatException {
            try {
                return Month.valueOf(s.toUpperCase()).ordinal() + 1;
            } catch (IllegalArgumentException e) {
                throw new WrongDateFormatException(Messages.WRONG_MONTH_NAME);
            }
        }
    }

    enum Weekday {
        SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;

        private static Weekday[] values;
        static {
            values = Weekday.values();
        }
        static String getWeekdayName(int index) {
            if(index > values.length - 1){
                return "Unknown";
            }
            String monthName = values[index].toString();
            return Character.toUpperCase(monthName.charAt(0)) + monthName.substring(1).toLowerCase();
        }
    }

    public void parseDate(String... args) throws WrongDateFormatException {

        final int DAY = 0;
        final int MONTH = 1;
        final int YEAR = 2;

        try {
            if (args.length == 0) {
                throw new WrongDateFormatException(Messages.ENTER_THE_DATE);
            }

            this.day = Integer.parseInt(args[DAY]);
            this.month = Month.getMonthIndex(args[MONTH]);
            this.year = Integer.parseInt(args[YEAR]);

            if (this.day < 1 || this.day > 31) {
                throw new WrongDateFormatException(Messages.WRONG_DAY);
            }
            if (this.year <= GREGORIAN_YEAR) {
                throw new WrongDateFormatException(String.format(Messages.WRONG_YEAR, GREGORIAN_YEAR));
            }

        } catch (NumberFormatException e) {
            throw new WrongDateFormatException(Messages.WRONG_FORMAT);
        }
    }

    /**
     * Formula taken from:
     * http://uk.wikipedia.org/wiki/Алгоритм_обчислення_дня_тижня
     * Note: I would like to move out "magic numbers" to constants, but I don't know exactly what they mean here
     */
    public String getWeekdayName() {

        int a = (int) Math.floor((14 - month) / 12);
        int y = year - a;
        int m = month + (12 * a) - 2;
        int weekDayIndex = (7000 + (day + y + (int) Math.floor(y / 4) - (int) Math.floor(y / 100) + (int) Math.floor(y / 400) + (31 * m) / 12)) % 7;

        return Weekday.getWeekdayName(weekDayIndex);
    }

    public static void main(String[] args) {
        CalendarSeeker calendarSeeker = new CalendarSeeker();
        try {
            calendarSeeker.parseDate(args);
        } catch (WrongDateFormatException e) {
            System.out.println(e.getMessage());
            return;
        }
        String weekdayName = calendarSeeker.getWeekdayName();
        System.out.println(weekdayName);

    }
}
